import React, { memo, useCallback, useEffect, useState } from 'react';
import { Input, Tree, TreeDataNode, TreeProps, Typography, Badge, Skeleton } from 'antd';
import '../styles/datasetlist.scss';
import { SvgIcon } from '@/components/icon';
import { useDatasetStore } from '@/store/datasetStore';
import { DatasetListItem, DatasetTypeEnum } from '@/common';
import { CaretDownOutlined, DownOutlined, SearchOutlined, RightOutlined } from '@ant-design/icons';
import { DatasetEvent, TreeData } from '@/types/dataset';
import { DatasetsContext } from '../context';
import { useContextSelector } from 'use-context-selector';
import { useMount, useTrackedEffect, useUpdate, useUpdateLayoutEffect } from 'ahooks';
import {
  transformToTreeItems,
  getNodeParent,
  getBackground,
  getNodeParentType,
  filterTree,
} from '@/utils/tree';
import { useDatasets, useDatasetsActions } from '@/store/datasetsStore';
import { getDatasetIcon } from '../utils/icon';
const { TreeNode } = Tree;

interface Props {
  dataLoading: Boolean;
}

const DatasetsTree = ({ dataLoading }: Props) => {
  // const [items, setItems] = useState<TreeData[]>([]);
  const { allDatasets, expandedKeys, setExpandedKeys, updateExpandedKeys } = useDatasetStore();
  const { expandKeys } = useDatasets();
  const { setDataset } = useDatasetsActions();

  const {
    selectedTreeData,
    fullTreeData,
    event$,
    setSelectedTreeData,
    selectedTreeNode,
    currentDataset,
    setCurrentDataset,
    setSelectedTreeNode,
    setFullTreeData,
  } = useContextSelector(DatasetsContext, (s) => s);
  const [searchValue, setSearchValue] = useState('');
  const [firstLoad, setFirstLoad] = useState(true);
  const [firstLoadNode, setFirstLoadNode] = useState(true);
  const update = useUpdate();
  const getKeys = (prevExpandedKeys: string[], selected: string | null) => {
    if (!selected || !prevExpandedKeys) {
      return;
    }
    if (prevExpandedKeys.includes(selected)) {
      return prevExpandedKeys.filter((key) => key !== selected);
    } else {
      return [...prevExpandedKeys, selected];
    }
  };

  const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
    if (info.node.type == 'file') {
      return;
    }

    console.log(expandedKeys.includes(info.node.id));

    if (expandedKeys.includes(info.node.id)) {
      const keys = expandedKeys.filter((item) => item != info.node.id);
      setExpandedKeys(keys);
    } else {
      // const keys = [info.node.id, ...expandedKeys];
      // setExpandedKeys(keys);
    }

    updateSelectedDatasetTree(info.node, selectedKeys.length > 0);
    selectedKeys.length > 0
      ? setSelectedTreeNode(info.node)
      : info.node.parentKey
        ? setSelectedTreeNode(info.node.parent)
        : setSelectedTreeNode(null);
    event$?.emit(DatasetEvent.DATASETTREECLICKED);
  };

  const onExpand: TreeProps['onExpand'] = (expandedKeys, node) => {
    const keys = expandedKeys.map((item) => item.toString());
    setExpandedKeys(keys);
    update();
    setDataset({
      expandKeys: keys,
    });
  };

  const updateSelectedDatasetTree = (node: TreeData, expand?: true) => {
    const tree: TreeData[] = [];
    tree.push(node);
    getNodeParent(tree, node);
    if (tree && tree.length > 0) {
      expand
        ? setSelectedTreeData(tree.reverse())
        : setSelectedTreeData(tree.reverse().slice(0, -1));
      // expand ? setSelectedTreeData(tree.reverse()) : setSelectedTreeData([])
    }
  };

  const findNodeById = (nodes: TreeData[], id: string): TreeData | undefined => {
    for (const node of nodes) {
      if (node.id == id) {
        return node;
      }
      if (node.children) {
        const found = findNodeById(node.children, id);
        if (found) {
          return found;
        }
      }
    }
    return undefined;
  };

  useEffect(() => {
    if (selectedTreeNode && selectedTreeNode.children && selectedTreeNode.children.length > 0) {
      const keys = getKeys(expandedKeys, selectedTreeNode.id);
      setExpandedKeys(keys ?? []);
      update();
    }
    if (selectedTreeNode) {
      if (selectedTreeNode.type == 'dataset') {
        setCurrentDataset(selectedTreeNode);
      } else {
        setCurrentDataset(getNodeParentType(selectedTreeNode.parent, 'dataset'));
      }
    }
  }, [selectedTreeNode]);

  useEffect(() => {
    if (selectedTreeNode) {
      const id = selectedTreeNode?.id;
      const node = findNodeById(fullTreeData, id);
      if (node) {
        node.name = selectedTreeNode.name;
        // node.children = selectedTreeNode.children;
        update();
      }
    }
  }, [selectedTreeNode?.name, selectedTreeNode?.children]);

  const updateData = useCallback(() => {
    const treeItems = transformToTreeItems(allDatasets, undefined, true);
    setFullTreeData(treeItems);
    if (selectedTreeNode) {
      const node = findNodeById(treeItems, selectedTreeNode.id);
      console.log(
        node?.children != selectedTreeNode.children,
        node?.children,
        selectedTreeNode.children,
      );

      if (node?.children != undefined) {
        setSelectedTreeNode(node);
      }
    }
    if (selectedTreeData && selectedTreeData.length > 0) {
      const nodes = selectedTreeData.map((item) => {
        const node = findNodeById(treeItems, item.id);
        return node;
      });
      setSelectedTreeData(nodes.filter((item) => item != undefined));
    } else {
      if (firstLoad && expandKeys && expandKeys.length > 0) {
        const nodes = expandKeys.map((item) => {
          const node = findNodeById(treeItems, item);
          return node;
        });
        const filterData = nodes.filter((item) => item != undefined);
        setSelectedTreeData(filterData);
        setExpandedKeys(expandKeys ?? []);
        setSelectedTreeNode(
          filterData && filterData.length > 0 ? filterData[filterData.length - 1] : null,
        );
        setFirstLoad(false);
      }
    }
  }, [allDatasets, selectedTreeNode, firstLoad, firstLoadNode, expandKeys]);

  // useTrackedEffect(
  //   (changes) => {
  //     if (changes?.includes(0)) {
  //       updateData
  //       // update();
  //     }
  //   },
  //   [allDatasets, selectedTreeNode, firstLoad, firstLoadNode, expandKeys],
  // );

  // useEffect(()=>{
  //   updateData();
  // },[]);

  useEffect(() => {
    updateData();
  }, [allDatasets]);

  const titleRender = (node: TreeData) => {
    const { id, name, key, type, count } = node;

    if (type == 'file') {
      return null;
    }
    return (
      <div className="flex items-center self-center p-1" style={{ fontSize: '16' }}>
        <div
          className="mr-2 flex-shrink-0 items-center justify-center rounded-lg"
          style={{
            color: getBackground(type),
          }}
        >
          {getDatasetIcon(node, expandedKeys, false)}
        </div>
        <div
          className="flex-1 text-sm"
          style={{ color: id == selectedTreeNode?.id ? '#6D35FF' : '#000' }}
        >
          {name}
        </div>
        {/* {type == 'folder' && (
          <div className="ml-2 flex-shrink-0 rounded-xl bg-[#E5DCFF]">
            <span className="ml-3 mr-3">{count}</span>
          </div>
        )} */}
      </div>
    );
  };

  // useMount(()=>{
  //   console.log(expandKeys);

  // }, [firstLoad]);

  return (
    <div className="mb-4 w-full overflow-y-hidden overflow-x-hidden rounded-xl">
      <Input
        style={{ border: 'none', background: '#F5F7FB' }}
        placeholder="搜索..."
        className="mb-2 text-sm"
        value={searchValue}
        prefix={<SearchOutlined style={{ color: '#C9CEE2', marginRight: '10px' }} />}
        onChange={(e) => {
          setSearchValue(e.target.value);
        }}
      />
      {dataLoading && (
        <div className="h-full w-full items-center p-2">
          <Skeleton active paragraph={{ rows: 24 }} />
        </div>
      )}
      <Tree
        className="tree rounded-xl"
        defaultExpandedKeys={expandedKeys}
        defaultSelectedKeys={[expandedKeys[expandedKeys.length - 1]]}
        expandedKeys={expandedKeys}
        onExpand={onExpand}
        onSelect={onSelect}
        treeData={filterTree(fullTreeData, searchValue, true, DatasetTypeEnum.api)}
        titleRender={titleRender}
        switcherIcon={<DownOutlined />}
      ></Tree>
    </div>
  );
};

export default memo(DatasetsTree);
